<?php defined('SYSPATH') OR die('No direct access allowed.');

//v0.1.1

class User_Message{
	
	private $session_var = 'um';
	private $messages = array(
			'error' => array(),
			'alert' => array(),
			'info' => array(),
			'debug' => array(),
		);
	private $templates = array(
			'error' => '',
			'alert' => '',
			'info' => '',
			'debug' => '',
		);
	private $has_changed = FALSE;
	
	
	public function User_Message()
	{
		Kohana::log('debug', 'User Message module initialized.');
		foreach ($this->templates as $k=>$v) {
			$this->templates[$k] = 
				Kohana::config('user_message.'.$k.'_template')==FALSE ? 
				Kohana::config('user_message.default_template') : 
				Kohana::config('user_message.'.$k.'_template');
		}
		
		$sv = Kohana::config('user_message.session_var');
		$this->session_var = $sv ? $sv : $this->session_var;
		
		//save the messages if any changes have been made
		Event::add('system.post_controller', array($this, '_save_session'));
		
		$this->_load_session();
	}
	
	/**
	 * Loads unread messages from the session array
	 * @return unknown_type
	 */
	private function _load_session()
	{
		$saved = Kohana::instance()->session->get($this->session_var,$this->messages);
		if (is_array($saved)) $this->messages = $saved;
		
	}
	
	/**
	 * Saves the unread messages into the session array
	 * 
	 * @return unknown_type
	 */
	public function _save_session()
	{
		if ($this->has_changed)
			Kohana::instance()->session->set($this->session_var,$this->messages);
	}
	
	/**
	 * Empty the session array
	 * _save session will take care of the rest...
	 * 
	 * @return void
	 */
	private function _del_session()
	{
		$this->messages = array(
			'error' => array(),
			'alert' => array(),
			'info' => array(),
			'debug' => array(),
		);
	}
	
	
	/**
	 * Add a new message
	 * 
	 * @param $message
	 * @param $type
	 * @return null
	 */
	public function add($message, $type='info')
	{
		if (isset($this->messages[$type])) $this->messages[$type][] = $message;
		else
		{
			Kohana::log('alert', 'Undefined message type "'.$type.'".');
			$this->messages[$type]['debug'] = $message;
		}
		$this->has_changed = TRUE;
	}
	
	/**
	 * Add a new message type
	 * 
	 * @param $type
	 * @param $template
	 * @return void
	 */
	public function add_type($type, $template='')
	{
		$this->messages[$type] = array();
		$this->templates[$type] = 
			empty($template) ? 
				(
					Kohana::config('user_message.'.$k.'_template')==FALSE ? 
						Kohana::config('user_message.'.'default_template') : 
						Kohana::config('user_message.'.$k.'_template')
				)
				: $template;
		$this->has_changed = TRUE;
	}
	
	/**
	 * Sets the template paramater to a message type or all of them
	 * 
	 * @param $template
	 * @param $type
	 * @return void
	 */
	public function set_template($template, $type=FALSE)
	{
		if ($type==FALSE) 
			foreach ($this->templates as $k=>$v) $this->templates[$k] = $template;
		elseif (isset($this->templates[$type]))
			$this->templates[$type] = $template;
		else
		{
			Kohana::log('alert', 'Undefined message type "'.$type.'", template not set.');
		}
	}
	
	/**
	 * Render messages
	 * 
	 * @param $type
	 * @return string
	 */
	public function render($type=FALSE)
	{
		$tmp = '';
		if (isset($this->templates[$type]))
		{
			$tmp = $this->_render_type($type);
		}
		else
		{
			if ($type!=FALSE) Kohana::log('warning', 'Undefined message type "'.$type.'", all messages rendered.');
			foreach (array_keys($this->templates) as $type) $tmp .= $this->_render_type($type);
		}
		if ($tmp)
		{
			 $this->_del_session();
			 $this->has_changed = TRUE;
		}
		return $tmp;
	}
	
	/**
	 * Render a specific message type
	 * 
	 * @param $type
	 * @return unknown_type
	 */
	private function _render_type($type)
	{
		if (empty($this->templates[$type])) return '';
		
		$tmp = '';
		foreach ($this->messages[$type] as $k=>$v)
		{
			if (is_string($v)) $v = array('message' => $v);
			$view = new View($this->templates[$type], $v);
			$tmp .= $view->render(FALSE);
		}
		return $tmp;
	}

	/**
	 * Magically converts view object to string.
	 *
	 * @return  string
	 */
	public function __toString()
	{
		try
		{
			return $this->render();
		}
		catch (Exception $e)
		{
			// Display the exception using its internal __toString method
			return (string) $e;
		}
	}
}